{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "假设我们有两个特征向量 `hidden_state1` 和 `hidden_state2`，并且它们分别有维度 `feature_dim1` 和 `feature_dim2`。我们还假设你有一个标签向量 `labels`，它包含你将要预测的分类标签。\n",
    "\n",
    "这段代码首先定义了一个特征融合分类器 `FeatureFusionClassifier`，该分类器具有一个用于分类的全连接层。在 `forward` 方法中，我们通过连接两个隐藏状态向量来实现特征融合，并通过全连接层获取分类的 logits。最后，我们使用交叉熵损失函数计算分类的损失。\n",
    "\n",
    "注意：这里的示例使用了随机生成的数据来模拟两个隐层的输出，实际应用中这些输出应该来自于你的神经网络模型的隐层。标签 `labels` 也是随机生成的，你应该用真实的标签数据来替换它们以进行训练。\n",
    "\n",
    "当你有两个不同层的隐状态，并希望将它们融合以进行分类时，你可以通过连接（concatenation）或其他融合策略来实现。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "class FeatureFusionClassifier(nn.Module):\n",
    "    def __init__(self, feature_dim1, feature_dim2, num_classes):\n",
    "        super(FeatureFusionClassifier, self).__init__()\n",
    "    \n",
    "        # 特征融合后的维度\n",
    "        self.fused_feature_dim = feature_dim1 + feature_dim2\n",
    "    \n",
    "        # 全连接层用于分类\n",
    "        self.fc = nn.Linear(self.fused_feature_dim, num_classes)\n",
    "    \n",
    "    def forward(self, hidden_state1, hidden_state2):\n",
    "        # 特征融合（这里我们使用连接作为融合方法）\n",
    "        fused_features = torch.cat((hidden_state1, hidden_state2), dim=1)\n",
    "    \n",
    "        # 分类\n",
    "        logits = self.fc(fused_features)\n",
    "    \n",
    "        return logits\n",
    "\n",
    "# 示例参数\n",
    "feature_dim1 = 128\n",
    "feature_dim2 = 64\n",
    "num_classes = 10\n",
    "batch_size = 32\n",
    "\n",
    "# 初始化分类器\n",
    "classifier = FeatureFusionClassifier(feature_dim1, feature_dim2, num_classes)\n",
    "\n",
    "# 模拟两个隐层输出\n",
    "hidden_state1 = torch.randn(batch_size, feature_dim1)\n",
    "hidden_state2 = torch.randn(batch_size, feature_dim2)\n",
    "\n",
    "# 获取分类logits\n",
    "logits = classifier(hidden_state1, hidden_state2)\n",
    "\n",
    "# 假设有一个标签向量用于监督学习\n",
    "labels = torch.randint(0, num_classes, (batch_size,))\n",
    "\n",
    "# 计算损失（这里使用交叉熵损失）\n",
    "loss = F.cross_entropy(logits, labels)\n",
    "\n",
    "print(f\"Logits shape: {logits.shape}\")\n",
    "print(f\"Loss: {loss.item()}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "融合之后需要进行分类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "# 假设我们有一个简单的网络结构，其中包含两个隐藏层\n",
    "class SimpleNet(nn.Module):\n",
    "    def __init__(self, input_dim, hidden_dim1, hidden_dim2, num_classes):\n",
    "        super(SimpleNet, self).__init__()\n",
    "        self.layer1 = nn.Linear(input_dim, hidden_dim1)\n",
    "        self.layer2 = nn.Linear(hidden_dim1, hidden_dim2)\n",
    "        # 特征融合层\n",
    "        self.fusion_layer = nn.Linear(hidden_dim1 + hidden_dim2, num_classes)\n",
    "\n",
    "    def forward(self, x):\n",
    "        hidden_state1 = F.relu(self.layer1(x))  # 第一个隐藏层的输出\n",
    "        hidden_state2 = F.relu(self.layer2(hidden_state1))  # 第二个隐藏层的输出\n",
    "    \n",
    "        # 特征融合：连接两个隐藏状态\n",
    "        fused_features = torch.cat((hidden_state1, hidden_state2), dim=1)\n",
    "    \n",
    "        # 分类输出\n",
    "        logits = self.fusion_layer(fused_features)\n",
    "        return logits\n",
    "\n",
    "# 示例参数\n",
    "input_dim = 784  # 假设输入是28x28的图像，已经展平为784维向量\n",
    "hidden_dim1 = 256  # 第一个隐藏层的维度\n",
    "hidden_dim2 = 128  # 第二个隐藏层的维度\n",
    "num_classes = 10  # 假设有10个类别进行分类\n",
    "\n",
    "# 初始化网络\n",
    "net = SimpleNet(input_dim, hidden_dim1, hidden_dim2, num_classes)\n",
    "\n",
    "# 创建一个模拟输入（一批图像）\n",
    "batch_size = 64\n",
    "x = torch.randn(batch_size, input_dim)  # 模拟一批输入数据\n",
    "\n",
    "# 前向传播获取分类logits\n",
    "logits = net(x)\n",
    "\n",
    "# 假设我们有一批真实的标签\n",
    "labels = torch.randint(0, num_classes, (batch_size,))\n",
    "\n",
    "# 计算损失（使用交叉熵损失）\n",
    "loss = F.cross_entropy(logits, labels)\n",
    "\n",
    "print(f\"Logits shape: {logits.shape}\")  # 应该输出[batch_size, num_classes]\n",
    "print(f\"Loss: {loss.item()}\")  # 输出损失值"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
